package com.yourcompany.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yourcompany.api.dto.LoginLogQueryDTO;
import com.yourcompany.api.entity.LoginLog;
import com.yourcompany.api.mapper.LoginLogMapper;
import com.yourcompany.api.service.LoginLogService;
import com.yourcompany.common.utils.WebUtils;
import cn.hutool.http.useragent.UserAgent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class LoginLogServiceImpl extends ServiceImpl<LoginLogMapper, LoginLog> implements LoginLogService {
    
    @Override
    @Async
    public void recordLoginLog(LoginLog loginLog) {
        // 设置登录时间
        loginLog.setLoginTime(LocalDateTime.now());
        
        // 如果没有设置IP，则获取当前请求的IP
        if (StringUtils.isBlank(loginLog.getLoginIp())) {
            loginLog.setLoginIp(WebUtils.getIpAddr());
        }
        
        // 如果没有设置地理位置，则解析IP获取位置
        if (StringUtils.isBlank(loginLog.getLoginLocation())) {
            loginLog.setLoginLocation(WebUtils.getLocationByIp(loginLog.getLoginIp()));
        }
        
        // 解析User-Agent
        if (StringUtils.isNotBlank(loginLog.getUserAgent())) {
            UserAgent userAgent = WebUtils.parseUserAgent(loginLog.getUserAgent());
            loginLog.setOs(userAgent.getOs().getName());
            loginLog.setBrowser(userAgent.getBrowser().getName());
        }
        
        // 异步保存日志
        save(loginLog);
    }
    
    @Override
    public LoginLog getLastLoginLog(Long userId) {
        return baseMapper.getLastLoginLog(userId);
    }
    
    @Override
    public IPage<LoginLog> pageLoginLogs(IPage<LoginLog> page, LoginLogQueryDTO queryDTO) {
        LambdaQueryWrapper<LoginLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getUserId() != null, LoginLog::getUserId, queryDTO.getUserId())
                .like(StringUtils.isNotBlank(queryDTO.getUsername()), LoginLog::getUsername, queryDTO.getUsername())
                .eq(StringUtils.isNotBlank(queryDTO.getLoginType()), LoginLog::getLoginType, queryDTO.getLoginType())
                .eq(StringUtils.isNotBlank(queryDTO.getLoginIp()), LoginLog::getLoginIp, queryDTO.getLoginIp())
                .eq(StringUtils.isNotBlank(queryDTO.getDeviceId()), LoginLog::getDeviceId, queryDTO.getDeviceId())
                .eq(queryDTO.getStatus() != null, LoginLog::getStatus, queryDTO.getStatus())
                .ge(StringUtils.isNotBlank(queryDTO.getStartTime()), LoginLog::getLoginTime, queryDTO.getStartTime())
                .le(StringUtils.isNotBlank(queryDTO.getEndTime()), LoginLog::getLoginTime, queryDTO.getEndTime())
                .orderByDesc(LoginLog::getLoginTime);
        
        return page(page, wrapper);
    }
    
    @Override
    @Async
    public void cleanLoginLogs(int days) {
        LocalDateTime time = LocalDateTime.now().minusDays(days);
        LambdaQueryWrapper<LoginLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.le(LoginLog::getLoginTime, time);
        remove(wrapper);
    }
} 